#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# 导入树莓派GPIO库和时间模块
import RPi.GPIO as GPIO
import time

# 电机控制引脚定义
# EA:电机使能端，用于PWM调速 I1/I2:方向控制端
EA, I2, I1 = (13, 19, 26)
# 按钮输入引脚定义
BTN1, BTN2 = (6, 5)
# PWM频率设置为50Hz（适合直流电机）
FREQUENCY = 50

# 占空比等级预设值（0%,20%,40%,60%,80%,100%）
DUTYS = (0, 20, 40, 60, 80, 100)
# 当前占空比等级索引（初始为最高100%）
duty_level = len(DUTYS) - 1

# 初始化GPIO设置
GPIO.setmode(GPIO.BCM)  # 使用BCM引脚编号方案
# 配置电机控制引脚为输出模式
GPIO.setup([EA, I2, I1], GPIO.OUT)
# 初始化电机控制引脚电平：EA/I2低电平，I1高电平
GPIO.output([EA, I2], GPIO.LOW)
GPIO.output(I1, GPIO.HIGH)
# 配置按钮引脚为输入模式，启用内部上拉电阻，保持高电平
GPIO.setup([BTN1, BTN2], GPIO.IN, 
    pull_up_down = GPIO.PUD_UP)

# 创建PWM对象，初始占空比为100%
pwm = GPIO.PWM(EA, FREQUENCY)           # 创建PWM对象，频率为50Hz
pwm.start(DUTYS[duty_level])            # 设置初始占空比为100%并启动电机
print("duty = %d" % DUTYS[duty_level])  # 打印初始占空比

# 按钮检测函数（按下返回True）
def btn_pressed(btn):
    # 当按钮按下时引脚变为低电平（上拉模式）
    return GPIO.input(btn) == GPIO.LOW

# 更新占空比等级函数
def update_duty_level(delta):
    global duty_level
    old = duty_level  # 记录当前等级
    # 计算新占空比等级
    duty_level = (duty_level + delta) % len(DUTYS)
    # 应用新占空比到PWM输出
    pwm.ChangeDutyCycle(DUTYS[duty_level])
    # 打印信息（旧占空比 --> 新占空比）
    print("duty: %d --> %d" % (DUTYS[old], DUTYS[duty_level]))

# 记录按钮释放状态，用于消抖处理
btn1_released = True  # BTN1设置为释放
btn2_released = True  # BTN2设置为释放

try:
    # 主循环：持续检测按钮状态
    while True:
        # 处理btn1（降低速度按钮）
        if btn1_released:  # 当btn1按钮处于释放状态时
            if btn_pressed(BTN1):  # 检测到按下信号
                time.sleep(0.01)   # 消抖延时10ms
                if btn_pressed(BTN1):      # 再次确认是否按下
                    update_duty_level(-1)  # 降低占空比等级
                    btn1_released = False  # 标记为已按下
        else:  # 按钮处于按下状态时
            if not btn_pressed(BTN1):  # 若未检测到按钮已按下
                btn1_released = True   # 释放按钮
        
        # 处理btn2（提高速度按钮）
        if btn2_released:  # 当btn1按钮处于释放状态时
            if btn_pressed(BTN2):  # 检测到按下信号
                time.sleep(0.01)   # 消抖延时10ms
                if btn_pressed(BTN2):     # 再次确认是否按下
                    update_duty_level(1)  # 提高占空比等级
                    btn2_released = False # 标记为已按下
        else: # 按钮处于按下状态时
            if not btn_pressed(BTN2): # 若未检测到按钮已按下
                btn2_released = True  # 释放按钮

# 捕获Ctrl+C中断信号
except KeyboardInterrupt:
    pass

# 清理资源
pwm.stop()        # 停止PWM输出
GPIO.cleanup()    # 清理GPIO端口